<template>
  <div>
    <el-col :span="24">
      <div class="block">
        <el-date-picker
          v-model="value2"
          type="datetimerange"
          :shortcuts="shortcuts"
          range-separator="To"
          start-placeholder="起始日期"
          end-placeholder="结束日期"
          :default-time="['00:00:00', '00:00:00']" 
        />
        <el-select v-model="value3" placeholder="选择区域" style="width: 240px">
          <el-option v-for="item in options" :key="item.value" :label="item.label" :value="item.value" />
        </el-select>
      </div>
    </el-col>
    <div ref="chart" style="height: 500px; width: 1300px"></div>
    <div style="margin-top: 20px;">
      <el-button @click="toggleTableVisibility">
        {{ showTable ? '' : '' }}
      </el-button>
      <el-button @click="clearCompensationData">
        
      </el-button>
    </div>
    <el-table :data="tableData" style="width: 100%; margin-top: 20px" v-show="showTable" border>
      <el-table-column prop="station" label="工位" width="250" align="center" />
      <el-table-column label="平均JPH" width="250" align="center">
        <template #default="{ row }">
          {{ row.averageJPH.toFixed(2) }}
        </template>
      </el-table-column>
      <el-table-column label="目标JPH" width="250" align="center">
        <template #default="{ row }">
          <el-input 
            v-model.number="row.targetJPH" 
            @change="updateChartData(row)"
            size="small"
            placeholder="请输入"
          />
        </template>
      </el-table-column>
      <el-table-column label="补偿JPH" width="300" align="center">
        <template #default="{ row }">
          <el-input 
            v-model.number="row.compensationJPH" 
            @change="updateAverageJPH(row)"
            size="small"
            placeholder="请输入"
          />
        </template>
      </el-table-column>
      <el-table-column label="累计补偿JPH" width="250" align="center">
        <template #default="{ row }">
          {{ row.cumulativeCompensationJPH.toFixed(2) }}
        </template>
      </el-table-column>
      <el-table-column label="效率目标(%)" width="250" align="center">
        <template #default="{ row }">
          <el-input 
            v-model.number="row.efficiencyTarget" 
            @change="updateChartData(row)"
            size="small"
            placeholder="请输入"
          />
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, watch } from "vue";
import * as echarts from "echarts";
import axios from "axios";

const value2 = ref([]);
const showTable = ref(false);
const shortcuts = [
  {
    text: "当天",
    value: () => {
      const now = new Date();
      const start = new Date(now.getFullYear(), now.getMonth(), now.getDate());
      return [start, now];
    },
  },
];
const value3 = ref('get_BK_M1_hourly_production_data/');
const options = [
  {value: "get_LoopA_hourly_production_data/",label: "装配A"},
  {value: "get_LoopB_hourly_production_data/",label: "装配B"},
  {value: "get_LoopC_hourly_production_data/",label: "装配C"},
  {value: "get_BK_M1_hourly_production_data/",label: "缸体M1"},
  {value: "get_Bk_M2_hourly_production_data/",label: "缸体M2"},
  {value: "get_HD_M1_hourly_production_data/",label: "缸盖M1"},
  {value: "get_HD_M2_hourly_production_data/",label: "缸盖M2"},
  {value: "get_Ck_M1_hourly_production_data/",label: "曲轴"},
];

const chart = ref(null);
let chartInstance;
const tableData = ref([]);

function toggleTableVisibility() {
  showTable.value = !showTable.value;
}

function clearCompensationData() {
  tableData.value.forEach(item => {
    item.compensationJPH = 0;
    item.cumulativeCompensationJPH = 0;
    item.averageJPH = item.originalAverageJPH;
  });
  saveData();
  updateChart();
}

function loadSavedData() {
  const savedData = JSON.parse(localStorage.getItem('savedTableData')) || {};
  tableData.value.forEach(item => {
    const savedItem = savedData[item.station] || {};
    item.compensationJPH = savedItem.compensationJPH || 0;
    item.cumulativeCompensationJPH = savedItem.cumulativeCompensationJPH || 0;
    item.averageJPH = item.originalAverageJPH + item.cumulativeCompensationJPH;
    item.targetJPH = savedItem.targetJPH || item.targetJPH;
    item.efficiencyTarget = savedItem.efficiencyTarget || 96;
  });
}

function saveData() {
  const savedData = {};
  tableData.value.forEach(item => {
    savedData[item.station] = {
      compensationJPH: item.compensationJPH,
      cumulativeCompensationJPH: item.cumulativeCompensationJPH,
      targetJPH: item.targetJPH,
      efficiencyTarget: item.efficiencyTarget
    };
  });
  localStorage.setItem('savedTableData', JSON.stringify(savedData));
}

function updateAverageJPH(row) {
  row.averageJPH = row.originalAverageJPH + row.cumulativeCompensationJPH + row.compensationJPH;
  row.cumulativeCompensationJPH += row.compensationJPH;
  saveData();
  updateChart();
}

function updateChartData() {
  saveData();
  updateChart();
}

onMounted(() => {
  const now = new Date();
  const end = new Date(now.getFullYear(), now.getMonth(), now.getDate(), now.getHours(), 5, 0, 0);
  const start = new Date(now.setHours(8, 0, 0, 0));

  value2.value = [start, end];
  fetchData();
  loadSavedData();
  tableData.value.forEach(item => {
    item.originalAverageJPH = item.averageJPH;
  });
});

function formatDate(d: string) {
  const date = new Date(d);
  const YY = date.getFullYear() + "-";
  const MM = (date.getMonth() + 1).toString().padStart(2, '0') + "-";
  const DD = date.getDate().toString().padStart(2, '0');
  const hh = date.getHours().toString().padStart(2, '0') + ":";
  const mm = date.getMinutes().toString().padStart(2, '0') + ":";
  const ss = date.getSeconds().toString().padStart(2, '0');
  return `${YY}${MM}${DD} ${hh}${mm}${ss}`;
}

watch([value2, value3], ([newValue2, newValue3]) => {
  const start_time = formatDate(newValue2[0]);
  const end_time = formatDate(newValue2[1]);
  const start = new Date(start_time);
  const end = new Date(end_time);
  const diffTime = Math.abs(end.getTime() - start.getTime());
  let diffHours = Math.floor(diffTime / (1000 * 60 * 60)); 

  if (end.getMinutes() > 5) {
    diffHours += 1;
  }

  fetchData(start_time, end_time, newValue3, diffHours);
});

async function fetchData(startTime, endTime, assembly, diffHours) {
  try {
    const productionUrl = `http://10.64.35.32:8000/man_ana_sql_server/${assembly}?start_time=${startTime}&end_time=${endTime}&page_size=10001`;
    const productionResponse = await axios.get(productionUrl);
    const productionData = productionResponse.data;

    const targetTimeUrl = 'http://10.64.35.32:8000/manufacture_analysis/get_ms_cycle_data/?page_size=1000';
    const targetTimeResponse = await axios.get(targetTimeUrl);
    const targetTimeData = targetTimeResponse.data;

    const processedData = processHourlyProductionData(productionData, diffHours);

    const targetTimes = {};
    const equipmentEfficiency = {};

    targetTimeData.forEach(item => {
      targetTimes[item.station] = item.equipment_target_time;
      if (item.push_pull_target_time && processedData[0][item.station] !== undefined) {
        equipmentEfficiency[item.station] = ((processedData[0][item.station] / item.push_pull_target_time) * 100).toFixed(2);
      }
    });

    Object.keys(processedData[0]).forEach(key => {
      if (key.startsWith('OP') || key.startsWith('M1_op') || key.startsWith('M2_op') || key.startsWith('HD_M1_op') || key.startsWith('HD_M2_op') || key.startsWith('CK_M1_op')) {
        processedData[0][`target_${key}`] = targetTimes[key] || 0;
        processedData[0][`efficiency_${key}`] = parseFloat(equipmentEfficiency[key] || 0);
      }
    });

    initChart(processedData);
    loadSavedData();
  } catch (error) {
    console.error(error);
  }
}

function processHourlyProductionData(data, diffHours) {
  const excludedStations = ['M1_oplg01','CK_M1_op008','CK_M1_op010g','CK_M1_op015a','CK_M1_op015b','CK_M1_op020g','CK_M1_op048','CK_M1_op075','M1_op075','M1_op125','M1_op195','M2_op075','M2_op125','HD_M1_op065','HD_M1_op145','HD_M1_op175','HD_M1_op178','HD_M2_op065','HD_M2_op145','HD_M2_op175','HD_M2_op178','M2_op195','M1_oplg02','OP1006', 'OP1008','OP1035','OP1040','OP2040','OP2100','OP2115','OP2120','OP2135','OP213a','OP2145','OP2146','OP2150','OP2155','OP2196','OP2225','OP2236','OP2260','OP2270','OP2325','OP2330','OP2355','OP2356','OP2380','OP2420','OP2430','OP2440','OP2450','OP2476','OP2505','OP2515','OP5010','OP5020','OP6010','OP7010','OP7020','OP7030','OP303a','OP305b','OP3062','OP3063','OP3105','OP2006','OP2055','OP1070','OP1075','OP1095','OP1096','OP1115','OP1126','OP1150','OP1165','OP1195','OP1196','OP121a','OP121b','OP1235','OP1245','OP4010','OP1130','OP1290','OP1265','OP1266','OP1315','OP1366','OP1368','OP143b','OP1405','OP1416','OP1420','OP1445','OP4050','OP4020','OP1053','OP1058'];
  const hourlySum = {};

  data.forEach((item, index) => { 
    if (index === 0) return;

    const prevItem = data[index - 1];
    const productionDiff = calculateHourlyProduction(item, prevItem);

    Object.keys(productionDiff).forEach(key => {
      if (!hourlySum[key]) hourlySum[key] = 0;
      hourlySum[key] += productionDiff[key];
    });
  });

  const averageProduction = {};

  Object.keys(hourlySum).forEach(key => {
    if (excludedStations.includes(key)) return;
    if (key.startsWith('OP') || key.startsWith('M1_op') || key.startsWith('M2_op') || key.startsWith('HD_M1_op') || key.startsWith('HD_M2_op') || key.startsWith('CK_M1_op')) {
      averageProduction[key] = diffHours > 0 ? (hourlySum[key] / diffHours) : 0;
    }
  });

  return [{ ...averageProduction }];
}

function calculateHourlyProduction(currentData, prevData) {
  const result = { ...currentData };
  const keys = Object.keys(currentData);
  keys.forEach(key => {
    if (key.startsWith('OP') || key.startsWith('M1_op') || key.startsWith('M2_op') || key.startsWith('HD_M1_op') || key.startsWith('HD_M2_op') || key.startsWith('CK_M1_op')) {
      result[key] = Math.max(currentData[key] - (prevData[key] || 0), 0);
    }
  });
  delete result.timestamp;
  return result;
}

function initChart(data) {
  if (!chartInstance) {
    chartInstance = echarts.init(chart.value);
  }

  const xAxisData = Object.keys(data[0]).filter(k => k.startsWith('OP') || k.startsWith('M1_op') || k.startsWith('M2_op') || k.startsWith('HD_M1_op') || k.startsWith('HD_M2_op') || k.startsWith('CK_M1_op'));
  const seriesData = Object.values(data[0]).filter(v => typeof v === 'number').map(v => parseFloat(v.toFixed(2)));
  const targetSeriesData = xAxisData.map(station => data[0][`target_${station}`] || 0);
  const efficiencySeriesData = xAxisData.map(station => data[0][`efficiency_${station}`] || 0);
  const efficiencyTarget = xAxisData.map(() => 96);

  tableData.value = xAxisData.map((station, index) => {
    const savedData = JSON.parse(localStorage.getItem('savedTableData')) || {};
    const savedItem = savedData[station] || {};
    const cumulativeCompensationJPH = savedItem.cumulativeCompensationJPH || 0;
    const originalAverageJPH = seriesData[index];
    const averageJPH = originalAverageJPH + cumulativeCompensationJPH;
    const targetJPH = savedItem.targetJPH || targetSeriesData[index];
    const efficiencyTargetValue = savedItem.efficiencyTarget || 96;

    return {
      station,
      averageJPH,
      targetJPH,
      compensationJPH: 0,
      cumulativeCompensationJPH,
      originalAverageJPH,
      efficiencyTarget: efficiencyTargetValue
    };
  });

  const updatedSeriesData = tableData.value.map(item => item.averageJPH);
  const updatedTargetSeriesData = tableData.value.map(item => item.targetJPH);
  const updatedEfficiencyTarget = tableData.value.map(item => item.efficiencyTarget);

  const option = {
    tooltip: {
      trigger: 'axis',
      formatter: (params) => {
        const stationName = params[0].name;
        const formattedName = stationName.match(/(OP.+|op.+)/i)?.[0] || stationName;
        let result = `<div>${formattedName}</div>`;
        params.forEach(param => {
          if (['设备效率', '效率目标'].includes(param.seriesName)) {
            result += `<div>${param.seriesName}: ${param.value}%</div>`;
          } else {
            result += `<div>${param.seriesName}: ${param.value.toFixed(2)}</div>`;
          }
        });
        return result;
      },
    },
    legend: {
      data: ['平均JPH', '目标JPH', '设备效率', '效率目标'],
      orient: "horizontal",
      left: "left",
      top: "top",
      itemGap: 10,
    },
    title: {
      text: '平均小时产量统计',
      left: 'center',
      textStyle: { color: 'black' },
      subtext: '单位：JPH',
      subtextStyle: { fontWeight: 'bold' },
    },
    xAxis: {
      name: '工位',
      type: 'category',
      axisLabel: {
        rotate: 45,
        formatter: (value) => {
          const match = value.match(/(OP.+|op.+)/i);
          return match ? match[0] : value;
        },
      },
      data: xAxisData,
    },
    yAxis: [
      {
        type: 'value',
        name: '产量 (台/小时)',
        axisLabel: { formatter: '{value} JPH' }
      },
      {
        type: 'value',
        name: '设备效率 (%)',
        position: 'right',
        axisLine: { show: false, lineStyle: { color: 'black' } },
        axisLabel: { formatter: '{value}%' }
      }
    ],
    series: [
      {
        name: '平均JPH',
        type: 'bar',
        data: updatedSeriesData,
        itemStyle: {
          color: (params) => {
            const value = params.value;
            const target = updatedTargetSeriesData[params.dataIndex];
            return value >= target ? '#00ff00' : '#ffa500';
          }
        },
        label: {
          show: true,
          position: 'top',
        }
      },
      {
        name: '目标JPH',
        type: 'line',
        data: updatedTargetSeriesData,
        yAxisIndex: 0,
        symbol: 'circle',
        symbolSize: 5,
        lineStyle: {
          color: '#A5A3F7',
          width: 2
        },
        itemStyle: {
          color: '#A5A3F7'
        }
      },
      {
        name: '设备效率',
        type: 'line',
        data: efficiencySeriesData,
        yAxisIndex: 1,
        symbol: 'circle',
        symbolSize: 5,
        lineStyle: {
          color: '#CC6CE7',
          width: 2
        },
        itemStyle: {
          color: '#CC6CE7'
        },
        label: {
          show: true,
          position: 'top',
          formatter: '{c}%',
          color: 'black',
        }
      },
      {
        name: '效率目标',
        type: 'line',
        data: updatedEfficiencyTarget,
        yAxisIndex: 1,
        symbol: 'none',
        lineStyle: {
          color: '#0000ff',
          width: 2,
          type: 'dashed'
        },
        itemStyle: {
          color: '#0000ff'
        }
      }
    ],
    dataZoom: [
      { type: 'slider', show: true, start: 0, end: 100, top: '97%' },
      { type: 'inside', start: 90, end: 100 },
    ],
  };

  chartInstance.setOption(option);

  window.addEventListener('resize', () => {
    if (chartInstance) {
      chartInstance.resize();
    }
  });
}

function updateChart() {
  const newData = tableData.value.map(item => item.averageJPH);
  const newTargetData = tableData.value.map(item => item.targetJPH);
  const newEfficiencyTarget = tableData.value.map(item => item.efficiencyTarget);

  chartInstance.setOption({
    series: [
      {
        name: '平均JPH',
        data: newData,
        itemStyle: {
          color: (params) => {
            const value = params.value;
            const target = newTargetData[params.dataIndex];
            return value >= target ? '#00ff00' : '#ffa500';
          }
        }
      },
      {
        name: '目标JPH',
        data: newTargetData
      },
      {
        name: '效率目标',
        data: newEfficiencyTarget
      }
    ]
  });
}
</script>

<style scoped>
</style>